package com.yanqu.road.entity.activity.jiuzhou.game;

import com.yanqu.road.entity.enums.activity.jiuzhou.eJiuZhouAttributeEnum;
import com.yanqu.road.entity.enums.activity.jiuzhou.eJiuZhouBattleUserType;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 战斗用户数据对象
 */
public class CrossJiuZhouGameBattleUserData {

    private long userId;

    /**
     * 血量上限
     */
    private int maxHp;

    /**
     * 当前血量
     * 造成伤害时需要更新房间内用户的血量，镜像不影响
     */
    private int hp;

    /**
     * 额外血量 护盾
     */
    private int extraHp;

    /**
     * 可选择的锦囊
     */
    private List<Integer> skillId3List = new ArrayList<>();

    /**
     * 已选锦囊
     */
    private int chooseSkillId3;

    /**
     * 生效的技能列表(天时，棋书，锦囊，士气)
     */
    private Set<Integer> skillIds = new HashSet<>();

    /**
     * 战斗的门客数据(实时)
     */
    private Map<Integer, CrossJiuZhouGamePatronsData> patronsDataMap = new ConcurrentHashMap<>();

    /**
     * 用户类型
     * 0:正常  1:镜像               99:npc（测试用）
     *
     * 镜像的话不会对玩家的血量造成伤害
     */
    private int userType;

    /**
     * 镜像id(镜像时需要把这个当成userId给客户端)
     */
    private long mirrorUserId;

    /**
     * 鼓舞的银两数
     */
    private BigInteger silverBuff = BigInteger.ZERO;

    /**
     * 技能触发回合
     */
    private Map<Integer, Integer> skillEffectRoundMap = new HashMap<>();

    /**
     * 战斗相关属性
     */
    private Map<eJiuZhouAttributeEnum, Object> attributeMap = new HashMap<>();

    /**
     * 锦囊刷新次数
     */
    private int refreshTimes = 0;


    public CrossJiuZhouGameBattleUserData clone() {
        CrossJiuZhouGameBattleUserData battleUserData = new CrossJiuZhouGameBattleUserData();
        battleUserData.setUserId(this.userId);
        battleUserData.setMaxHp(this.maxHp);
        battleUserData.setHp(this.hp);
        battleUserData.setExtraHp(this.extraHp);
        battleUserData.setSkillId3List(new ArrayList<>(this.skillId3List));
        battleUserData.setChooseSkillId3(this.chooseSkillId3);
        battleUserData.setSkillIds(new HashSet<>(this.skillIds));
        Map<Integer, CrossJiuZhouGamePatronsData> newPatronsDataMap = new ConcurrentHashMap<>();
        for (CrossJiuZhouGamePatronsData gamePatronsData : this.patronsDataMap.values()) {
            newPatronsDataMap.put(gamePatronsData.getPatronsId(), gamePatronsData.clone());
        }
        battleUserData.setPatronsDataMap(newPatronsDataMap);
        battleUserData.setUserType(this.userType);
        battleUserData.setSilverBuff(new BigInteger(this.silverBuff.toString()));
        battleUserData.setSkillEffectRoundMap(new HashMap<>(this.skillEffectRoundMap));
        battleUserData.setAttributeMap(new HashMap<>(this.attributeMap));
        battleUserData.setMirrorUserId(this.mirrorUserId);
        battleUserData.setRefreshTimes(this.refreshTimes);
        return battleUserData;
    }

    public long getUserId() {
        return userId;
    }

    public void setUserId(long userId) {
        this.userId = userId;
    }

    public int getMaxHp() {
        return maxHp;
    }

    public void setMaxHp(int maxHp) {
        this.maxHp = maxHp;
    }

    public int getHp() {
        return hp;
    }

    public void setHp(int hp) {
        this.hp = hp;
    }

    public void hpChange(int offsetHp) {
        this.hp = Math.max(0, Math.min(maxHp, hp + offsetHp));
    }

    public int getExtraHp() {
        return extraHp;
    }

    public void setExtraHp(int extraHp) {
        this.extraHp = extraHp;
    }

    /**
     * 护盾无上限
     */
    public void extraHpChange(int offsetExtraHp) {
        this.extraHp = Math.max(0, extraHp + offsetExtraHp);
    }

    public List<Integer> getSkillId3List() {
        return skillId3List;
    }

    public void setSkillId3List(List<Integer> skillId3List) {
        this.skillId3List = skillId3List;
    }

    public int getChooseSkillId3() {
        return chooseSkillId3;
    }

    public void setChooseSkillId3(int chooseSkillId3) {
        this.chooseSkillId3 = chooseSkillId3;
    }

    public Set<Integer> getSkillIds() {
        return skillIds;
    }

    public void setSkillIds(Set<Integer> skillIds) {
        this.skillIds = skillIds;
    }

    public Map<Integer, CrossJiuZhouGamePatronsData> getPatronsDataMap() {
        return patronsDataMap;
    }

    public CrossJiuZhouGamePatronsData getPatronsData(int patronsId) {
        return patronsDataMap.get(patronsId);
    }

    public void setPatronsDataMap(Map<Integer, CrossJiuZhouGamePatronsData> patronsDataMap) {
        this.patronsDataMap = patronsDataMap;
    }

    public int getUserType() {
        return userType;
    }

    public void setUserType(int userType) {
        this.userType = userType;
    }

    public BigInteger getSilverBuff() {
        return silverBuff;
    }

    public void setSilverBuff(BigInteger silverBuff) {
        this.silverBuff = silverBuff;
    }

    public Map<Integer, Integer> getSkillEffectRoundMap() {
        return skillEffectRoundMap;
    }

    public void setSkillEffectRoundMap(Map<Integer, Integer> skillEffectRoundMap) {
        this.skillEffectRoundMap = skillEffectRoundMap;
    }

    public Map<eJiuZhouAttributeEnum, Object> getAttributeMap() {
        return attributeMap;
    }

    /**
     * 获取战斗属性
     */
    public <T> T getAttribute(eJiuZhouAttributeEnum attributeEnum, T defaultValue) {
        Object value = this.attributeMap.get(attributeEnum);
        return (value != null) ? (T) value : defaultValue;
    }

    /**
     * 获取战斗属性
     */
    public <T> T getAttribute(eJiuZhouAttributeEnum attributeEnum) {
        return getAttribute(attributeEnum, null);
    }

    public void putAttribute(eJiuZhouAttributeEnum attributeEnum, Object value) {
        this.attributeMap.put(attributeEnum, value);
    }

    public void setAttributeMap(Map<eJiuZhouAttributeEnum, Object> attributeMap) {
        this.attributeMap = attributeMap;
    }

    public long getMirrorUserId() {
        return mirrorUserId;
    }

    public void setMirrorUserId(long mirrorUserId) {
        this.mirrorUserId = mirrorUserId;
    }

    /**
     * 是否镜像
     */
    public boolean isMirror() {
        return userType == eJiuZhouBattleUserType.Mirror.getValue();
    }

    public int getRefreshTimes() {
        return refreshTimes;
    }

    public void setRefreshTimes(int refreshTimes) {
        this.refreshTimes = refreshTimes;
    }
}
